package com.ticket.sass.admin.manager

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper
import com.ticket.sass.admin.service.impl.*
import com.ticket.sass.admin.util.EscapeUtil
import com.ticket.sass.common.entity.provider.TenantWxaConfigEntity
import com.ticket.sass.common.entity.tenant.*
import com.ticket.sass.common.entity.tenant.enums.*
import com.ticket.sass.common.exception.enums.ErrorCode
import com.ticket.sass.common.exception.exception.BadRequestException
import com.ticket.sass.common.wxpay.WxPayClient
import org.springframework.stereotype.Component
import java.math.BigDecimal
import java.time.LocalDateTime
import java.util.stream.Collectors

@Component
class OrderManager (
    private val couponUserMapService: CouponUserMapServiceImpl,
    private val orderCouponMapService: OrderCouponMapServiceImpl,
    private val wxPayConfigService: WxPayConfigServiceImpl,
    private val wxaConfigService: TenantWxaConfigServiceImpl,
    private val generateSerialNumber: GeneratorCodeManager,
    private val memberCardOrderRecordService: MemberCardOrderRecordServiceImpl,
    private val orderMixedService: OrderMixedServiceImpl,
    private val orderPayService: OrderPayServiceImpl
) {

     fun refundCoupon(order: OrderEntity){
        if (order.useCoupon) {
            val couponMapEntities: List<OrderCouponMapEntity> = orderCouponMapService.listBy(order.id, "order_id")
            if (couponMapEntities.isNotEmpty()) {
                val couponUserMapIds =
                    couponMapEntities.stream().map { obj: OrderCouponMapEntity -> obj.couponUserMapId }
                        .collect(Collectors.toList())
                couponUserMapService.update(
                    UpdateWrapper<CouponUserMapEntity>().set("use_state", 0).`in`("id", couponUserMapIds)
                )
            }
        }
    }

    fun saveTransactionRecord(order: OrderEntity, memberCard: MemberCardEntity) {
        val transactionRecord = MemberCardOrderRecordEntity().apply {
            serialNumber = generateSerialNumber.orderNo("")
            flowType = MemberCardOrderRecordFlowType.INCOME
            type = MemberCardOrderRecordType.REFUND
            desc = getOrderDescription(order)
            amount = order.payPrice
            balance = memberCard.balance
            createdAt = LocalDateTime.now()
            userId = order.userId
            fromOrderId = order.id
            cardId = memberCard.id
        }
        memberCardOrderRecordService.save(transactionRecord)
    }

    fun refundToWeChat(order: OrderEntity, orderMixedEntity : OrderMixedEntity?) {
        val payPrice = if (orderMixedEntity != null) {
            orderMixedEntity.payPrice
        } else {
            order.payPrice
        }

        println("退款金额$payPrice")

        // 判断 payPrice 是否为 0
        if (payPrice.compareTo(BigDecimal.ZERO) == 0) {
            println("退款金额为0，不执行退款操作")
            // 终止方法
            return
        }


        val tenantId = order.tenantId
        val tenantWxaConfig = getTenantWxaConfig(tenantId)
        val wxConfig = getWxConfig()
        val wxPayClient = WxPayClient(tenantWxaConfig.appid, wxConfig.mchId, wxConfig.mchKey, wxConfig.p12Content)

        wxPayClient.initiateRefund(
            order.orderNo, payPrice, payPrice,
            "业务退款", ""
        )
    }

    fun updateOrderMixedStatus(orderMixedId: Long?) : OrderMixedEntity {
        val orderMixed = orderMixedService.getById(orderMixedId).apply {
            payStatus = OrderPayStatus.REFUND_SUCCESS
            orderMixedService.updateById(this)
        }

        orderPayService.getOneByOrderMixedId(orderMixedId).apply {
            payStatus = OrderPayStatus.REFUND_SUCCESS
            orderPayService.updateById(this)
        }

        return orderMixed
    }

    private fun getWxConfig(): WxPayConfigEntity {
        val wxPayConfig = wxPayConfigService.getOne(null)
            ?: throw BadRequestException(
                ErrorCode.BUSINESS_ERROR,
                EscapeUtil.errorMessage("config", "影院未设置租户微信支付配置")
            )

        if (wxPayConfig.p12Content.isNullOrEmpty()) {
            throw BadRequestException(
                ErrorCode.BUSINESS_ERROR,
                EscapeUtil.errorMessage("config", "影院未设置租户微信支付配置=>P12证书")
            )
        }

        return wxPayConfig
    }

    private fun getTenantWxaConfig(tenantId: Long): TenantWxaConfigEntity {
        return wxaConfigService.getConfigsByTenantId(tenantId)
            ?: throw BadRequestException(
                ErrorCode.BUSINESS_ERROR,
                EscapeUtil.errorMessage("config", "租户未设置appID")
            )
    }

    private fun getOrderDescription(order: OrderEntity): String {
        return when {
            order.type == OrderType.TICKET && order.payType == OrderPayType.CARD -> "冻结金额退回"
            order.type == OrderType.TICKET -> "票订单退款"
            order.type == OrderType.COMMODITY -> "卖品订单退款"
            order.type == OrderType.CARD_RECHARGE -> "会员卡充值订单退款"
            order.type == OrderType.GROUP_PURCHASE_TICKET -> "拼单订单退款"
            else -> throw IllegalArgumentException("未知的订单类型: ${order.type}")
        }
    }
}